import configureStore from 'redux-mock-store'

import promiseMiddleware from 'middlewares/promiseMiddleware'
import 'libs/promise.finally'
import { identity } from 'libs/utils'

jest.useFakeTimers()

const FETCH_LIST = 'FETCH_LIST'
const middlewares = [promiseMiddleware]
let mockStore
let store

beforeEach(() => {
  mockStore = configureStore(middlewares)
  store = mockStore({})
})

it('should call next if there is no promise factory passed in', () => {
  const action = {
    type: FETCH_LIST,
    promise: null,
  }

  store.dispatch(action)

  expect(store.getActions()).toMatchObject([action])
})

it("should call `promise` as function if it's not a promise instance", () => {
  const action = {
    type: FETCH_LIST,
    promise: () => Promise.resolve(1),
  }

  store.dispatch(action)

  expect(store.getActions()).toMatchObject([{ type: FETCH_LIST }])
})

it('should resolve with `payload` and `action` when resolving promise', () => {
  const action = {
    type: FETCH_LIST,
    promise: () => Promise.resolve({ payload: 1 }),
  }

  expect(store.dispatch(action)).resolves.toMatchSnapshot()
})

it('should throw error when rejecting promise', () => {
  const action = {
    type: FETCH_LIST,
    promise: () => Promise.reject(new Error('Hi, boompppps!')),
  }

  expect(store.dispatch(action)).rejects.toMatchSnapshot()
})

it('should could be passing promise directly', () => {
  const action = {
    type: FETCH_LIST,
    promise: Promise.resolve({ payload: 1 }),
  }

  expect(store.dispatch(action)).resolves.toMatchSnapshot()
})

it('should could be added schema in meta', () => {
  const action = {
    type: FETCH_LIST,
    promise: Promise.resolve({ payload: 1 }),
    meta: {
      schema: 'SCHEMA',
    },
  }

  expect(store.dispatch(action)).resolves.toMatchSnapshot()
})

it('Support custom normalize', () => {
  const action = {
    type: FETCH_LIST,
    promise: Promise.resolve({ payload: 1 }),
    meta: {
      normalize: identity,
    },
  }

  expect(store.dispatch(action)).resolves.toMatchSnapshot()
})
